/* typehints:start */
import { People } from "../people";
import { GameRoot } from "../root";
/* typehints:end */

import { Npc } from "../npcs/npc";
import { RaceDefine } from "../defines/race_define";
import { animRemoveElement, makeDiv, waitNextFrame } from "../../core/utils/utils";

// 一个战斗单元
export class BattleUnit{
  constructor(root, data, type){
    /** @type {GameRoot} */
    this.root = root;

    /** @type {Npc} */
    this.npc = data instanceof Npc ? data : false;

    /** @type {People} */
    this.people = this.npc ? this.npc.people : data;

    // 战斗的哪一方
    this.type = type;

    /** @type {HTMLElement} */
    this.element = null;

    this.selectTip = { text: '', color: 'danger' };

    // 行动条
    this.actionNum = 0;

    // 当前动作
    this.action = {
      skill: null,
      targets: [],
      data: {}
    }
  }

  initialize(){
    this.createElement();
    // 更新数据
    this.drawElement();
  }

  createElement(){
    let battlePage = this.root.hud.parts.battlePage;
    let box = document.createElement('div');
    box.classList.add('unit');
    box.classList.add(this.type);

    let identity = this.people.getFirstIdentity();

    box.innerHTML = `
      <div class="identity min-text">
        ${identity || RaceDefine[this.people.data.race].text}
      </div>
      <div class="title">${this.people.data.name}</div>
      <div class="status_desc">
        <div class="prog hp"><i></i></div>
        <div class="prog mana"><i></i></div>
      </div>
      <div class="action"><i></i></div>
      <div class="selectTip"></div>

      <div class="alert-msg"></div>
    `;

    battlePage.trackLongPressAndClick(box, () => {

    }, () => {
      if(this.root.battleMgr.isPlayerSelectTarget){
        this.root.hud.parts.battlePage.handleSelectUnits(this);
        return;
      }
    }, {
      applyCssClass: ''
    });

    this.element = box;
  }

  drawElement(){
    let hpProg = this.element.querySelector('.hp i');
    let manaProg = this.element.querySelector('.mana i');
    let action = this.element.querySelector('.action i');

    let hp = this.people.data.useAttr.hp > 0 ? this.people.data.useAttr.hp : 0;
    let mana = this.people.data.useAttr.mana > 0 ? this.people.data.useAttr.mana : 0;

    hpProg.style.width = ((hp / this.people.data.attr.hpMax) || 0) * 100 + '%';
    manaProg.style.width = ((mana / this.people.data.attr.manaMax) || 0) * 100 + '%';

    let actionNum = this.actionNum > 0 ? this.actionNum : 0;
    action.style.height = (actionNum / this.root.battleMgr.actionMaxNum) * 100 + '%';

    if(this.actionNum >= this.root.battleMgr.actionMaxNum){
      this.element.classList.add('active')
    } else {
      this.element.classList.remove('active')
    }

    let selectTip = this.element.querySelector('.selectTip');
    selectTip.innerHTML = this.selectTip.text;
    selectTip.className = 'selectTip text-' + (this.selectTip.color || 'danger');
  }

  /**
   * 弹出简单信息
   * @param {*} msg 
   */
  showText(msg = '', colorType = '', icon = false){
    let alertMsg = this.element.querySelector('.alert-msg');
    let textDom = makeDiv(alertMsg, '', ['text', 'text-' + (colorType || 'default')], `
      ${icon ? `<img src="res/ui/icons/${icon}" />` : ''}
      ${msg}
    `);
    let w = alertMsg.offsetWidth;
    let h = alertMsg.offsetHeight;
    textDom.style.left = Math.random() * (w / 2) + w / 3 + 'px';
    textDom.style.top = Math.random() * (h / 4) + 'px';
    animRemoveElement(textDom, () => {
      alertMsg.removeChild(textDom);
    }, 400, 700)
  }

  /**
   * 弹出聊天框
   * @param {*} msg 
   * @param {*} colorType 
   */
  showMsg(msg = '', colorType = ''){
    let alertMsg = this.element.querySelector('.alert-msg');
    let msgDom = alertMsg.querySelector('.msg');

    if(msgDom){
      this.hideMsg(true).then(() => {
        this.showMsg(msg);
      })
    } else {
      msgDom = makeDiv(alertMsg, '', ['msg', 'text-' + (colorType || 'default')], `
        <div class="wrapper">
          <div>${msg}</div>
        </div>
      `);

      this.hideMsg();
    }
  }

  /**
   * 隐藏弹出聊天框
   * @param {*} noReadTime 
   * @returns 
   */
  hideMsg(noReadTime = false){
    let alertMsg = this.element.querySelector('.alert-msg');
    let msgDom = alertMsg.querySelector('.msg');
    let text = msgDom.innerText;
    let readTime = Math.max(2500, (text.length / 500) * 60 * 1000);

    return new Promise(resolve => {
      setTimeout(() => {
        msgDom = alertMsg.querySelector('.msg');
        if(!msgDom) {
          resolve();
          return;
        }
        animRemoveElement(msgDom, () => {
          alertMsg.removeChild(msgDom);
          resolve();
        }, 300)
      }, noReadTime ? 0 : readTime);
    })
  }

  addActionNum(){
    this.actionNum += this.people.getActionNum();
    if(this.actionNum >= this.root.battleMgr.actionMaxNum) {
      this.root.battleMgr.setActionUnit(this);
      this.actionNum = this.root.battleMgr.actionMaxNum;
    }
  }

  deleteAction(){
    this.action.targets.map(item => item.selectTip.text = '');
    this.action = {
      skill: null,
      targets: []
    }
  }

  endAction(){
    this.actionNum -= this.action.skill ? this.action.skill.getAction() * this.actionNum : this.actionNum;
    this.deleteAction();
  }

  update(){
    this.drawElement();
  }
}